package cuboku.cuboku;

import java.util.LinkedHashSet;
import java.util.Set;

import aima.core.agent.Action;
import aima.core.search.framework.ActionsFunction;
import aima.core.search.framework.ResultFunction;


public class CubokuFunctionFactory {
	private static ActionsFunction _actionsFunction = null;
	private static ResultFunction _resultFunction = null;
	

	public static ActionsFunction getActionsFunction() {
		if (null == _actionsFunction) {
			_actionsFunction = new EPActionsFunction();
		}
		return _actionsFunction;
	}

	public static ResultFunction getResultFunction() {
		if (null == _resultFunction) {
			_resultFunction = new EPResultFunction();
		}
		return _resultFunction;
	}

	private static class EPActionsFunction implements ActionsFunction {
		
		public Set<Action> actions(Object state) {
			
//			Cuboku cuboku = (Cuboku) state;

			Set<Action> actions = new LinkedHashSet<Action>();

			actions.add(CubokuLight.UNO);
			actions.add(CubokuLight.TRES);
			actions.add(CubokuLight.CUATRO);
			actions.add(CubokuLight.SEIS);
			actions.add(CubokuLight.SIETE);
			actions.add(CubokuLight.NUEVE);
			
			return actions;
		}
	}

	private static class EPResultFunction implements ResultFunction {
		public Object result(Object s, Action a) {
			CubokuLight cuboku = (CubokuLight) s;
			
			if (CubokuLight.UNO.equals(a)) {
				CubokuLight newCuboku = new CubokuLight(cuboku);
				newCuboku.mov1();
				return newCuboku;
			} else if (CubokuLight.TRES.equals(a)) {
				CubokuLight newCuboku = new CubokuLight(cuboku);
				newCuboku.mov3();
				return newCuboku;
			} else if (CubokuLight.CUATRO.equals(a)) {
				CubokuLight newCuboku = new CubokuLight(cuboku);
				newCuboku.mov4();
				return newCuboku;
			} else if (CubokuLight.SEIS.equals(a)) {
				CubokuLight newCuboku = new CubokuLight(cuboku);
				newCuboku.mov6();
				return newCuboku;
			} else if (CubokuLight.SIETE.equals(a)) {
				CubokuLight newCuboku = new CubokuLight(cuboku);
				newCuboku.mov7();
				return newCuboku;
			} else if (CubokuLight.NUEVE.equals(a)) {
				CubokuLight newCuboku = new CubokuLight(cuboku);
				newCuboku.mov9();
				return newCuboku;
			}

			// The Action is not understood or is a NoOp
			// the result will be the current state.
			return s;
		}
	}

}
